package com.amkai.aes.webservice.binary.objecthandler.casecosting;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;

import com.amkai.aes.aescommon.service.binary.job.casecosting.CaseCostingParameterJob;
import com.amkai.aes.aescommon.service.binary.job.casecosting.CaseCostingParameterResult;
import com.amkai.aes.generatedbeans.insurance.InsuranceCarrier;
import com.amkai.aes.generatedbeans.physstaff.Specialty;
import com.amkai.aes.generatedbeans.pmcase.CaseClassification;
import com.amkai.aes.generatedbeans.preferencecard.PreferenceCard;
import com.amkai.aes.generatedbeans.procedure.Procedure;
import com.amkai.aes.generatedbeans.procedure.items.ProcedureType;
import com.amkai.aes.generatedbeans.scheduling.resources.AppointmentType;
import com.amkai.aes.server.dictionary.QuickDictionaryItemProvider;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

public class CaseCostingParameterHandler implements JobObjectHandler<CaseCostingParameterJob, Serializable, CaseCostingParameterResult> {
	
	@Override
	public CaseCostingParameterResult process(CaseCostingParameterJob job, Serializable object) throws Exception {
		
		CaseCostingParameterResult res = new CaseCostingParameterResult();
		SessionManager sm = SiteManager.Start();
		
		switch (job.getKind()) {
		case PREFERENCE_CARD: {
			
			if (job.getSurgeonId() == null && job.getSpecialityId() == null)
				return null;
			
			String query = " select pref FROM PreferenceCard pref " +
														" LEFT JOIN FETCH pref.provider as prov " +
														" LEFT JOIN FETCH pref.mainCode " +
														" LEFT JOIN FETCH pref.anestType " +
														" LEFT JOIN FETCH pref.specialty spec " +
														" where pref.deleted = 0 ";
			
			if (job.getSurgeonId() != null) {
				query += " AND prov = " + job.getSurgeonId();
			}
			else {
				query += " AND spec = " + job.getSpecialityId();
			}
			
			try {
				List<PreferenceCard> list = sm.execute(query).list();
				res.setKind(job.getKind());
				res.setPreferenceCardList(list);
				
				return res;
			}
			finally {
				sm.closeSession();
			}
			
		}
		//------- END of Preference Card
		
		case GROUP_LISTS: {
			QuickDictionaryItemProvider qdip = new QuickDictionaryItemProvider(sm, job.getModuleDepartment());
			
			res.setAppointmentTypeList(qdip.getItems(AppointmentType.class));
			res.setCaseClassificationList(qdip.getItems(CaseClassification.class));
			res.setInsuranceCarrierList(qdip.getItems(InsuranceCarrier.class));
			res.setSpecialtyList(qdip.getItems(Specialty.class));
			res.setProcedureTypeList(qdip.getItems(ProcedureType.class));
			res.setProcedureList(qdip.getItems(Procedure.class));
			
			// KKORNEL: AES-12411
			// AES-14478
			Query q = sm.execute(
					"SELECT physician FROM Physician physician " +
					"INNER JOIN physician.itemGroup physIg " +
					"WHERE " +
						"(physician.baseOrganization.id = :beId) AND " +
						"(physician.isProvider = true) AND " +
						"EXISTS(SELECT sr.id " + 
							"FROM SchedulingResource sr " +
							"INNER JOIN sr.reference ref " +
							"WHERE EXISTS(SELECT psr.id FROM PhysStaffReference psr " +
							"INNER JOIN psr.physStaff ph  " +
							"INNER JOIN ph.itemGroup phIg " +
							"WHERE (ref.id = psr.id) AND (phIg.id = physIg.id))" +
						")");
			q.setLong("beId", job.getModuleDepartment().getId());
			res.setSurgeonList(q.list());
			
			return res;
		}
		}
		return null;
	}

}
